#pragma once
#include "Socket.hpp"
#include "InetAddr.hpp"
#include <functional>
using namespace sock_ns;
static const uint16_t GPORT = 8888;

using server_IO_t = std::function<void(SockpPtr,InetAddr &)>;
class TcpServer
{
private:
    struct ThreadData
    {
        SockpPtr _sockfd;
        TcpServer *_self;
        InetAddr _addr;
        ThreadData(SockpPtr sockfd, TcpServer *self, const InetAddr &addr)
            : _sockfd(sockfd),
              _self(self),
              _addr(addr)
        {
        }
    };
    static void *handler(void *args)
    {
        pthread_detach(pthread_self()); // 分离线程
        ThreadData *td = static_cast<ThreadData *>(args);

        td->_self->_server(td->_sockfd, td->_addr);
        // 关闭sockfd
        td->_sockfd->Close();
        delete td;
        return nullptr;
    }

public:
    TcpServer(server_IO_t server, uint16_t port = GPORT)
        : _server(server), _listen_socket(std::make_shared<Tcp_socket>(port)),
          _port(port)
    {
        _listen_socket->BuildListenSocket(_port);
    }
    ~TcpServer()
    {
    }
    void Start()
    {
        _isrunnung = true;
        while (_isrunnung)
        {
            InetAddr client;

            SockpPtr newptr = _listen_socket->AcceptSocket(&client);
            if (!newptr)
                continue;

            LOG(INFO, "Get a new link,mssage = %s\n", client.GetAddrStr().c_str());
            // 交付线程执行task
            ThreadData *td = new ThreadData(newptr, this, client);
            pthread_t tid;
            pthread_create(&tid, nullptr, handler, td);
        }
        _isrunnung = false;
    }

private:
    uint16_t _port; // 端口号
    SockpPtr _listen_socket;
    bool _isrunnung = false;
    server_IO_t _server;
};